package com.uam.core.lk.utils;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.type.TypeFactory;
import com.uam.core.lk.utils.exception.SerializationException;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;

import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Date;

/**
 * @author 祝展
 * @version 1.0
 * @description  任意对象(支持泛型)与字符串的序列化和反序列化工具
 * @Date 2019/11/20 09:41
 **/
public class Object2JsonStrSerializer<T> {

    public static final Charset DEFAULT_CHARSET = StandardCharsets.UTF_8;

    private final JavaType javaType;

    private ObjectMapper objectMapper;

    public Object2JsonStrSerializer() {
        this.javaType = this.getJavaType(Object.class);
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        this.objectMapper = objectMapper;
    }

    private JavaType getJavaType(Class<?> clazz) {
        return TypeFactory.defaultInstance().constructType(clazz);
    }

    public void setObjectMapper(ObjectMapper objectMapper) {
        Assert.notNull(objectMapper, "'objectMapper' must not be null");
        this.objectMapper = objectMapper;
    }

    public T deserialize(@Nullable String str) throws SerializationException {
        try {
            byte[] bytes = str.getBytes(DEFAULT_CHARSET);
            return this.objectMapper.readValue(bytes, 0, bytes.length, this.javaType);
        } catch (Exception e) {
            throw new SerializationException("Could not read JSON: " + e.getMessage(), e);
        }
    }

    public String serialize(@Nullable Object t) throws SerializationException {
        try {
             byte[] bytes = this.objectMapper.writeValueAsBytes(t);
             return new String(bytes,DEFAULT_CHARSET);
        } catch (Exception e) {
            throw new SerializationException("Could not write JSON: " + e.getMessage(), e);
        }
    }

    public static void main(String[] args) {
        Object2JsonStrSerializer serializer = new Object2JsonStrSerializer();
        BB bb = new BB();
        bb.i=1;
        bb.L = 10L;
        bb.date = new Date();
        bb.str="BBBBB字符串";

        AA aa = new AA();
        aa.i=1;
        aa.L = 10L;
        aa.date = new Date();
        aa.str="AAAA字符串";
        aa.object = bb;

        String aaStr = serializer.serialize(aa);
        AA aaTemp = (AA)serializer.deserialize(aaStr);
        System.out.println();
    }

    public static class AA{
        public Date date;
        public int i;
        public Long L;
        public String str;
        public Object object;
    }

    public static class BB{
        public Date date;
        public int i;
        public Long L;
        public String str;
    }
}
